#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QStandardItemModel"
#include "QDebug"
#include "Robot.h"
#include "QMessageBox"
#include "QTime"
#include "string"
#include "iostream"
#include <QFile>
#include <QFileDialog>
#include "demonstratewidget.h"

#define heightJointItem 30
#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString styHeader("border-bottom-width: 0.5px;border-style: outset;border-color: rgb(229,229,229);");

    ui->twdDH->horizontalHeader()->setStyleSheet(styHeader);
    ui->twdDH->verticalHeader()->setStyleSheet(styHeader);
    ui->twdDH->setRowHeight(0,heightJointItem);

    ui->twdDH->resize(ui->gbxJoint->width(),ui->gbxJoint->height()); // 重新设置表格区域大小
    ui->twdDH->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   // 设置子项目等宽、、
    ui->twdDH->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->twdDH->setEditTriggers(QAbstractItemView::DoubleClicked);

    ui->twdSend->setEditTriggers(QAbstractItemView::DoubleClicked);
    ui->twdSend->resize(ui->gbxSend->width(),ui->gbxSend->height());
    ui->twdSend->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   // 设置子项目等宽、、
    ui->twdSend->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    ui->twdReceive->setEditTriggers(QAbstractItemView::DoubleClicked);
    ui->twdReceive->resize(ui->gbxReceive->width(),ui->gbxReceive->height());
    ui->twdReceive->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   // 设置子项目等宽、、
    ui->twdReceive->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    for(int i = 0;i < 6;i++)
    {
        QComboBox *cbx0 = new QComboBox;
        QComboBox *cbx1 = new QComboBox;
        QStringList strlst = {"标准帧","扩展帧"};
        cbx0->addItems(strlst);
        cbx1->addItems(strlst);
        ui->twdSend->setCellWidget(i,1,cbx0);
        ui->twdReceive->setCellWidget(i,2,cbx1);
        sendFilters.push_back(cbx0);
        receiveFilters.push_back(cbx1);
    }

    ui->twdControl->resize(ui->gbxControlMat->width(),ui->gbxControlMat->height());
    ui->twdControl->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);   // 设置子项目等宽、、
    ui->twdControl->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->twdControl->setEditTriggers(QAbstractItemView::NoEditTriggers);

    ui->ssdSpeed->setText("速度：");
    ui->ssdSpeed->setMinMax(0,100);
    connect(ui->ssdSpeed,SIGNAL(valueChanging(double)),this,SLOT(on_speedChanged(double)));
    ui->ssdSpeed->setValue(50);
    serial = new QSerialPort;
    canConnecter = new canCont::CAN_Connecter(*serial);
    ui->tabWidget->setTabEnabled(2,false);

    pgmCtrl = new ProgramControl(NULL,ui->vlayDemon);
    on_btnJointSure_clicked();

    QFile file("../RobotController/configuration.dat");
    if(file.open(QIODevice::ReadOnly))
    {
        QDataStream in(&file);
        DataSave_t sData;
        int size = sizeof(sData);
        uint8_t *pdata = (uint8_t*)&sData;
        for(int i = 0;i < size;i++)in >> (pdata[i]);

        ui->cbxBaudRate->setCurrentIndex(sData.bundrate);
        ui->cbxDataBits->setCurrentIndex(sData.dataBits);
        ui->cbxStopBit->setCurrentIndex(sData.stopBits);
        ui->cbxParity->setCurrentIndex(sData.parity);
        ui->cbxFlowControl->setCurrentIndex(sData.flowControl);
        vector<QComboBox*>::iterator it1 = sendFilters.begin();
        vector<QComboBox*>::iterator it2 = receiveFilters.begin();
        for(int i = 0;i < 6;i++)
        {
            ui->twdSend->item(i,0)->setText(QString("%1").arg(sData.canSendID[i],8,16));
            ui->twdReceive->item(i,0)->setText(QString("%1").arg(sData.canReceiveID[i],8,16));
            ui->twdReceive->item(i,1)->setText(QString("%1").arg(sData.canReceiveMASK[i],8,16));
            (*it1)->setCurrentIndex(sData.canSendType[i]);
            (*it2)->setCurrentIndex(sData.canReceiveType[i]);
            it1++;
            it2++;
            for(int j = 0;j < ui->twdDH->columnCount();j++)
            {
                ui->twdDH->item(i,j)->setText(QString("%1").arg(sData.joints[i][j]));
            }
        }
    }
    file.close();


}

MainWindow::~MainWindow()
{
    delete ui;
    delete serial;
    delete canConnecter;
}

/* @brief refresh the information of robot, then put them to the every model of display
 *        such as twdControl edtJoint
 */
void MainWindow::reloadInformationOfRobot()
{
    mat transfer = robot.T_froward;
    mat jointsAngle = robot.DH_Mat(span(),3);
    for(int i = 0;i < 4;i++)
    {
        for(int j = 0;j < 4;j++)
        {
            ui->twdControl->item(i,j)->setText(QString("%1").arg(transfer(i,j),0,'f',3));
        }
    }
//    for(int i = 0;i < robot.Joints.size();i++)
//    {
//        FrameData temp;
//        temp.dataDouble = jointsAngle(i,0);
//        canConnecter->sendData(jntCAN[i].jntSendIdSize,jntCAN[i].jntSendId,8,temp.dataU8);
//    }
    jointsAngle(span(),span()) = jointsAngle(span(),span()) * 180/PI;
    ui->edtJoint_1->setText(QString("%1°").arg(jointsAngle(0,0),0,'f',3));
    ui->edtJoint_2->setText(QString("%1°").arg(jointsAngle(1,0),0,'f',3));
    ui->edtJoint_3->setText(QString("%1°").arg(jointsAngle(2,0),0,'f',3));
    ui->edtJoint_4->setText(QString("%1°").arg(jointsAngle(3,0),0,'f',3));
    ui->edtJoint_5->setText(QString("%1°").arg(jointsAngle(4,0),0,'f',3));
    ui->edtJoint_6->setText(QString("%1°").arg(jointsAngle(5,0),0,'f',3));
}

/* @brief The callback function of ensure pushbutton of twdDH that was clicked
 *
 */
void MainWindow::on_btnJointSure_clicked()
{
    if(ui->btnJointSure->text() == "确定")
    {
        ui->btnJointSure->setText("取消");

        ui->twdDH->setStyleSheet(QString("background-color:#D3D3D3"));
        ui->btnJointSure->setStyleSheet(QString("background-color:#D3D3D3"));
        ui->twdDH->setEnabled(false);
        ui->gbxControlMat->setEnabled(true);
        ui->gbxJointControl->setEnabled(true);
        ui->gbxTemplate->setEnabled(true);
        ui->gbxDecareControl->setEnabled(true);
        ui->gbxSpeed->setEnabled(true);

        // reAdd the joints to robot
        robot.removeAllJoints();    // clear all the Joint in robot
        int a,alpha,d,theta_min,theta_max;
        for(int i = 0;i < 6;i++)
        {
            a = ui->twdDH->item(i,0)->text().toInt();
            alpha = ui->twdDH->item(i,1)->text().toInt();
            d = ui->twdDH->item(i,2)->text().toInt();
            theta_min = ui->twdDH->item(i,3)->text().toInt();
            theta_max = ui->twdDH->item(i,4)->text().toInt();
            Joint* joint = new Joint(Rotate,a,PI*alpha/180,d,0,PI*theta_min/180,PI*theta_max/180);
            robot.appendJoint(joint);
        }
        robot.DH_Mat.print();
        reloadInformationOfRobot();
    }
    else if(ui->btnJointSure->text() == "取消")
    {   // when the joints mat was changed
        ui->btnJointSure->setText("确定");

        ui->twdDH->setStyleSheet(QString("background-color:#FFFFFF"));
        ui->btnJointSure->setStyleSheet(QString("background-color:#B2DEEC"));
        ui->twdDH->setEnabled(true);
        ui->gbxControlMat->setEnabled(false);
        ui->gbxJointControl->setEnabled(false);
        ui->gbxTemplate->setEnabled(false);
        ui->gbxDecareControl->setEnabled(false);
        ui->gbxSpeed->setEnabled(false);
    }
}

/* @brief The callback function of ensure pushbutton of twdSend that was clicked
 */
void MainWindow::on_btnSendSure_clicked()
{
    if(ui->btnSendSure->text() == "确定")
    {
        int row = ui->twdSend->rowCount();
        vector<QComboBox*>::iterator it1 = sendFilters.begin();
        for(int i = 0;i < row;i++)
        {
            jntCAN[i].jntSendId = ui->twdSend->item(i,0)->text().toUInt(nullptr,16);
            if((*it1)->currentIndex() == 0)jntCAN[i].jntSendIdSize = Standard;
            else if((*it1)->currentIndex() == 1)jntCAN[i].jntSendIdSize = Expanded;
            cout<<"id: "<<jntCAN[i].jntSendId<< "type:" << jntCAN[i].jntSendIdSize;
            it1++;
        }

        ui->btnSendSure->setText("取消");
        ui->twdSend->setEnabled(false);
        ui->btnSendSure->setStyleSheet\
                (QString("background-color: qlineargradient(spread:pad, x1:0.5,\
                         y1:0, x2:0.5, y2:1, stop:0 #D3D3D3, stop:0.5 #D3D3D3, stop:1 #D3D3D3);"));
                ui->twdSend->setStyleSheet(QString("background-color:#D3D3D3"));
    }
    else if(ui->btnSendSure->text() == "取消")
    {
        ui->btnSendSure->setText("确定");
        ui->twdSend->setEnabled(true);
        ui->btnSendSure->setPalette(QPalette(QPalette::Button,QColor(60,60,60)));
        ui->btnSendSure->setStyleSheet\
                (QString("background-color: qlineargradient(spread:pad, x1:0.5, \
                         y1:0, x2:0.5, y2:1, stop:0 #B2DEEC, stop:0.5 #B2DEEC, stop:1 #B2DEEC);"));
                ui->twdSend->setStyleSheet(QString("background-color:#FFFFFF"));
    }
}

/* @brief The callback function of ensure pushbutton of twdReceive that was clicked
 */
void MainWindow::on_btnReceiveSure_clicked()
{
    if(ui->btnReceiveSure->text() == "确定")
    {
        int row = ui->twdReceive->rowCount();
        vector<QComboBox*>::iterator it1 = receiveFilters.begin();
        for(int i = 0;i < row;i++)
        {
            jntCAN[i].jntReceId = ui->twdReceive->item(i,0)->text().toUInt(nullptr,16);
            jntCAN[i].jntReceMask = ui->twdReceive->item(i,1)->text().toUInt(nullptr,16);

            if((*it1)->currentIndex() == 0)jntCAN[i].jntReceIdSize = Standard;
            else if((*it1)->currentIndex() == 1)jntCAN[i].jntReceIdSize = Expanded;
            it1++;
            cout<<"id: "<<jntCAN[i].jntReceId<<"Mask:"<< jntCAN[i].jntReceMask << "type:" << jntCAN[i].jntReceIdSize;
        }

        ui->btnReceiveSure->setText("取消");
        ui->twdReceive->setEnabled(false);
        ui->btnReceiveSure->setStyleSheet\
                (QString("background-color: qlineargradient(spread:pad, x1:0.5,\
                         y1:0, x2:0.5, y2:1, stop:0 #D3D3D3, stop:0.5 #D3D3D3, stop:1 #D3D3D3);"));
                ui->twdReceive->setStyleSheet(QString("background-color:#D3D3D3"));

    }
    else if(ui->btnReceiveSure->text() == "取消")
    {
        ui->btnReceiveSure->setText("确定");
        ui->twdReceive->setEnabled(true);
        ui->btnReceiveSure->setPalette(QPalette(QPalette::Button,QColor(60,60,60)));
        ui->btnReceiveSure->setStyleSheet\
                (QString("background-color: qlineargradient(spread:pad, x1:0.5, \
                         y1:0, x2:0.5, y2:1, stop:0 #B2DEEC, stop:0.5 #B2DEEC, stop:1 #B2DEEC);"));
                ui->twdReceive->setStyleSheet(QString("background-color:#FFFFFF"));
    }
}

/* @brief The callback function of XMoveAdd button pressed
 */
void MainWindow::on_btnXMoveAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(0,3) = posmat(0,3) + robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of XMoveSub button pressed
 */
void MainWindow::on_btnXMoveSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(0,3) = posmat(0,3) - robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of YMoveAdd button pressed
 */
void MainWindow::on_btnYMoveAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(1,3) = posmat(1,3) + robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of YMoveSub button pressed
 */
void MainWindow::on_btnYMoveSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(1,3) = posmat(1,3) - robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of ZMoveAdd button pressed
 */
void MainWindow::on_btnZMoveAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(2,3) = posmat(2,3) + robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of ZMoveSub button pressed
 */
void MainWindow::on_btnZMoveSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    posmat(2,3) = posmat(2,3) - robot.moveStep;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of XRotateAdd button pressed
 */
void MainWindow::on_btnXRotateAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {{1,0,0,0},\
                    {0,cos(robot.rotateStep),-sin(robot.rotateStep),0},\
                    {0,sin(robot.rotateStep), cos(robot.rotateStep),0},\
                    {0,0,0,1}
                   };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of XRotateSub button pressed
 */
void MainWindow::on_btnXRotateSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {{1,0,0,0},\
                    {0,cos(-robot.rotateStep),-sin(-robot.rotateStep),0},\
                    {0,sin(-robot.rotateStep), cos(-robot.rotateStep),0},\
                    {0,0,0,1}
                   };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of YRotateAdd button pressed
 */
void MainWindow::on_btnYRotateAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {
        { cos(robot.rotateStep),0,sin(robot.rotateStep),0},\
        {0,1,0,0},\
        {-sin(robot.rotateStep),0,cos(robot.rotateStep),0},\
        {0,0,0,1}
    };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of YRotateSub button pressed
 */
void MainWindow::on_btnYRotateSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {
        { cos(-robot.rotateStep),0,sin(-robot.rotateStep),0},\
        {0,1,0,0},\
        {-sin(-robot.rotateStep),0,cos(-robot.rotateStep),0},\
        {0,0,0,1}
    };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of ZRotateAdd button pressed
 */
void MainWindow::on_btnZRotateAdd_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {
        { cos(robot.rotateStep),-sin(robot.rotateStep),0,0},\
        { sin(robot.rotateStep), cos(robot.rotateStep),0,0},\
        {0,0,1,0},\
        {0,0,0,1}
    };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

/* @brief The callback function of ZRotateSub button pressed
 */
void MainWindow::on_btnZRotateSub_pressed()
{
    mat posmat = robot.T_froward; // get the initial pos.
    mat transfer = {
        { cos(-robot.rotateStep),-sin(-robot.rotateStep),0,0},\
        { sin(-robot.rotateStep), cos(-robot.rotateStep),0,0},\
        {0,0,1,0},\
        {0,0,0,1}
    };
    posmat = transfer * posmat;
    robot.ikine(posmat);
    reloadInformationOfRobot();
}

// TODO:
void MainWindow::on_btnJoint_1_Add_pressed()
{

}

void MainWindow::on_btnJoint_1_Sub_pressed()
{

}

void MainWindow::on_btnJoint_2_Add_pressed()
{

}

void MainWindow::on_btnJoint_2_Sub_pressed()
{

}

void MainWindow::on_btnJoint_3_Add_pressed()
{

}

void MainWindow::on_btnJoint_3_Sub_pressed()
{

}

void MainWindow::on_btnJoint_4_Add_pressed()
{

}

void MainWindow::on_btnJoint_4_Sub_pressed()
{

}

void MainWindow::on_btnJoint_5_Add_pressed()
{

}

void MainWindow::on_btnJoint_5_Sub_pressed()
{

}

void MainWindow::on_btnJoint_6_Add_pressed()
{

}

void MainWindow::on_btnJoint_6_Sub_pressed()
{

}

/* @brief on_tabWidget_tabBarClicked: when the tabConnect is clicked,connect the serial port.
 *
 */
void MainWindow::on_tabWidget_tabBarClicked(int index)
{
    if(index == -1) // the tabConnect was disable,so the index equals to -1
    {
        if(serial->isOpen())    // if the serial is opened
        {
            serial->close();
            QMessageBox::information(this,"通知","串口关闭成功！");
            ui->gbxSerial->setEnabled(true);
            return;
        }

        QString portName = ui->cbxCOM->currentText();
        serial->setPortName(portName);
        try {
            if(!serial->open(QIODevice::ReadWrite))
            {
                throw 1;
            }
        }  catch (int i) {
            if(i == 1)QMessageBox::critical(this,"错误！","串口打开失败，请重试！");
            return;
        }
        connect(serial, SIGNAL(readyRead()), this, SLOT(on_serialReceived()));

        QMessageBox::information(this,"通知","串口打开成功！");     // The serial was opened successfully
        canConnecter->setFilter(0,1,0,0);
        ui->gbxSerial->setEnabled(false);
        uint32_t baudrate = ui->cbxBaudRate->currentText().toUInt();
        serial->setBaudRate(baudrate);  // Set the BaudRate

        switch(ui->cbxDataBits->currentText().toUInt())     // set the data bits
        {
        case 5:serial->setDataBits(QSerialPort::Data5);break;
        case 6:serial->setDataBits(QSerialPort::Data6);break;
        case 7:serial->setDataBits(QSerialPort::Data7);break;
        case 8:serial->setDataBits(QSerialPort::Data8);break;
        default:break;
        }

        switch(ui->cbxStopBit->currentIndex())              // set the stop bits
        {
        case 0:serial->setStopBits(QSerialPort::OneStop);break;
        case 1:serial->setStopBits(QSerialPort::OneAndHalfStop);break;
        case 2:serial->setStopBits(QSerialPort::TwoStop);break;
        default:break;
        }

        switch(ui->cbxParity->currentIndex())              // set the parity bits
        {
        case 0:serial->setParity(QSerialPort::NoParity);break;
        case 1:serial->setParity(QSerialPort::EvenParity);break;
        case 2:serial->setParity(QSerialPort::OddParity);break;
        case 3:serial->setParity(QSerialPort::SpaceParity);break;
        case 4:serial->setParity(QSerialPort::MarkParity);break;
        default:break;
        }

        switch(ui->cbxFlowControl->currentIndex())              // set the flow control
        {
        case 0:serial->setFlowControl(QSerialPort::NoFlowControl);break;
        case 1:serial->setFlowControl(QSerialPort::HardwareControl);break;
        case 2:serial->setFlowControl(QSerialPort::SoftwareControl);break;
        default:break;
        }

    }
}

/* @brief on_pushButton_clicked:refesh the avaliablePorts
 *
 */
void MainWindow::on_pushButton_clicked()
{
    ui->cbxCOM->clear();        // clear all the item in cbxCOM
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        ui->cbxCOM->addItem(serial.portName());
    }
}

/* @brief on_serialReceived: when connecter send the data to pc,this function will be called
 *
 */
static uint8_t buf[500];
void MainWindow::on_serialReceived()
{
    QByteArray buffer = serial->readAll();
    for(int i = 0;i < (buffer.count()<500 ? buffer.count():500);i++)
    {
        buf[i] = buffer.at(i);
    }
    //qDebug()<<buffer;
    std::vector<canCont::ReceInfo> a = canConnecter->receiveInfo(buf,buffer.count());
    std::vector<canCont::ReceData> b = canConnecter->receiveData(buf,buffer.count());

    /*--------------- next is the test code ------------------------*/
    if(b.size())
    {
        canCont::ReceData* receEnd = &(b.back());
        for(int i = 0;i < robot.Joints.size();i++)
        {
            mat theta = robot.getTheta();
            if(receEnd->ID == jntCAN[i].jntReceId)
            {
                if(receEnd->type == TypeData)
                {
                    double temp = receEnd->frameData.dataDouble;//getChangedEndian(receEnd->frameData.dataU8,8);
                    theta(i,0) = temp;
                    robot.fkine(theta);
                    cout<<"关节"<<i+1<<"更新："<<theta(i,0);
                    reloadInformationOfRobot();
                }
                else if(receEnd->type == TypeRequest)
                {
                    uint64_t temp = getChangedEndian((uint8_t*)&(robot.DH_Mat(i,3)),8);
                    canConnecter->sendData(jntCAN[i].jntReceIdSize,jntCAN[i].jntSendId,8,(uint8_t*)&temp);
                }
            }

        }
    }
//        if(a.size())
//        {
//                    qDebug()<<"baudrate:"<<a.front().baudrate;
//                    qDebug()<<"errorRecent:"<<a.front().errorRecent;
//                    qDebug()<<"filterEnNum:"<<a.front().filterEnNum;
//                    qDebug()<<"offLine:"<<a.front().offLine;
//                    qDebug()<<"receiveErrorNum:"<<a.front().receiveErrorNum;
//                    qDebug()<<"receiveSuccessCount:"<<a.front().receiveSuccessCount;
//                    qDebug()<<"sendErrorNum:"<<a.front().sendErrorNum;
//                    qDebug()<<"sendCount:"<<a.front().sendCount;
//                    qDebug()<<"sendFailCount:"<<a.front().sendFailCount;
//                    qDebug()<<"sendSucessCount:"<<a.front().sendSucessCount;
//        }

}

void MainWindow::on_speedChanged(double value)
{
    robot.moveStep = value * 0.05;
    robot.rotateStep = value * 0.005;
}

/* @brief closeEvent: when the mainwindow closed this function will be called to save configuration
 *
 */
void MainWindow::closeEvent(QCloseEvent *event)
{
    QFile file("../RobotController/configuration.dat");
    if(file.open(QIODeviceBase::WriteOnly|QFile::Truncate))
    {
        QDataStream out(&file);
        DataSave_t data;
        data.bundrate = ui->cbxBaudRate->currentIndex();
        data.dataBits = ui->cbxDataBits->currentIndex();
        data.stopBits = ui->cbxStopBit->currentIndex();
        data.parity = ui->cbxParity->currentIndex();
        data.flowControl = ui->cbxFlowControl->currentIndex();
        vector<QComboBox*>::iterator it1 = sendFilters.begin();
        vector<QComboBox*>::iterator it2 = receiveFilters.begin();
        for(int i = 0;i < 6;i++)
        {
            data.canSendID[i] = ui->twdSend->item(i,0)->text().toUInt(nullptr,16);
            data.canReceiveID[i] = ui->twdReceive->item(i,0)->text().toUInt(nullptr,16);
            data.canReceiveMASK[i] = ui->twdReceive->item(i,1)->text().toUInt(nullptr,16);
            data.canSendType[i] = (*it1)->currentIndex();
            data.canReceiveType[i] = (*it2)->currentIndex();
            it1++;
            it2++;
            for(int j = 0;j < ui->twdDH->columnCount();j++)
            {
                data.joints[i][j] = ui->twdDH->item(i,j)->text().toDouble();
            }
        }
        int size = sizeof(data);
        uint8_t *pdata = (uint8_t*)&data;
        for(int i = 0;i < size;i++)out << (pdata[i]);
    }
    else cout << "文件未打开";
    file.close();
}


void MainWindow::on_btnRecord_clicked()
{
    pgmCtrl->createPos(robot.getTheta()*180/PI);
}


void MainWindow::on_btnAction_clicked()
{

}


void MainWindow::on_btnMoveTo_clicked()
{

}


void MainWindow::on_btnRun_clicked()
{

}



void MainWindow::on_btnRemoveAll_clicked()
{

}




void MainWindow::on_btnDelete_clicked()
{
    pgmCtrl->deletePos();
}


void MainWindow::on_btnSearchProgram_clicked()
{
    QFileInfo fi;
    fi = QFileInfo(QFileDialog::getOpenFileName(this));
    string path = fi.filePath().toStdString();
    if(path.length() == 0){
        qDebug()<<"no file or path find";
        return;
    }
    qDebug()<<"getted the file path"<<QString(path.c_str());
    ui->edtPrgramFile->setText(QString(path.c_str()));
    pgmCtrl->loadProgramFile(path);
}


void MainWindow::on_btnSaveProgram_clicked()
{
    QFileInfo fi;
    fi = QFileInfo(QFileDialog::getSaveFileName(this));
    string path = fi.filePath().toStdString();
    if(path.length() == 0){
        qDebug()<<"no file or path find";
        return;
    }
    qDebug()<<"getted the file path"<<QString(path.c_str());
    pgmCtrl->createProgramFile(path);
}

